package config

import (
	"go.uber.org/zap"
	"os"
	"strings"
	"sync"

	"gitee.com/xuyiping_admin/pkg/di"
	"gitee.com/xuyiping_admin/pkg/logger/zaplog"
)

const AppName = "kptDtm"

var (
	Module   = di.Provide(Options)
	options  *AppConfig
	appEnv   string
	initOnce sync.Once
)

// AppConfig store all configuration options
type AppConfig struct {
	AppName        string `yaml:"app_name"`
	AppEnv         string `yaml:"app_environment"`
	Debug          bool   `yaml:"debug" env:"APP_DEBUG"`
	HTTPServerAddr string `yaml:"http_server_addr" env:"HTTP_SERVER_ADDR"`

	// 数据库配置 额外加载文件部分 database.yaml
	StoreSetting StoreSetting `json:"store_setting" yaml:"store"`

	// DTM 配置
	DTMConfig   map[string]*DTMConfig `json:"dtm_config" yaml:"dtm"`
	CronSetting CronSetting           `json:"cron_setting" yaml:"cron"`
}

// StoreSetting 数据库配置
type StoreSetting struct {
	// 开启 SyDb SQL 记录
	DriverName string `yaml:"driver_name" json:"driver_name"`
	ShowSQL    bool   `yaml:"show_sql" json:"show_sql"`
	KptDtmRW   string `yaml:"kpt_dtm_rw" json:"kpt_dtm_rw"`
	KptDtmMigr string `yaml:"kpt_dtm_migr" json:"kpt_dtm_migr" `
}

type DTMConfig struct {
	LoginUrl    string `yaml:"login_url" json:"login_url"`
	CompanyUrl  string `yaml:"company_url" json:"company_url"`
	CompanyCode string `yaml:"company_code" json:"company_code"`
	UserName    string `yaml:"user_name" json:"user_name"`
	Password    string `yaml:"password" json:"password"`
	Request     struct {
		Count string `yaml:"count" json:"count"`
		Top   int    `yaml:"top" json:"top"`
	} `yaml:"request" json:"request"`
	// 云养牛 配置
	YYNConfig YYNConfig `json:"yyn_config" yaml:"yyn"`
}

type YYNConfig struct {
	Url      string `yaml:"url" json:"url"`
	FarmNum  string `yaml:"farm_num" json:"farm_num"`
	Secret   string `yaml:"secret" json:"secret"`
	UserName string `yaml:"user_name" json:"user_name"`
	Mqtt     Mqtt   `yaml:"mqtt" json:"mqtt"`
}

type Mqtt struct {
	ProductKey   string `yaml:"product_key" json:"product_key"`
	DeviceName   string `yaml:"device_name" json:"device_name"`
	DeviceSecret string `yaml:"device_secret" json:"device_secret"`
	Host         string `yaml:"host" json:"host"`
	HeartBeat    string `yaml:"heart_beat" json:"heart_beat"`
	TopicName    string `yaml:"topic_name" json:"topic_name"`
	Qos          int    `yaml:"qos" json:"qos"`
	Retained     bool   `yaml:"retained" json:"retained"`
	Body         Body   `yaml:"body" json:"body"`
}

type Body struct {
	ReqMethod string `yaml:"req_method" json:"req_method"`
	RegCode   string `yaml:"reg_code" json:"reg_code"`
	Command   string `yaml:"command" json:"command"`
	ApiId     string `yaml:"api_id" json:"api_id"`
	ModelType string `yaml:"model_type" json:"model_type"`
}

type CronSetting struct {
	// 是否启动任务时先跑一次
	CrontabStartRun bool `yaml:"crontab_start_run"`
	// CRONTAB 表达式
	DtmInit  string `yaml:"dtm_init"`
	DtmRetry string `yaml:"dtm_retry"`
}

func Options() *AppConfig {
	return options
}

func init() {
	appEnv = strings.ToLower(os.Getenv("APP_ENVIRONMENT"))
	zaplog.Info("app environment", zap.Any("app_env", appEnv))
	cfg := &AppConfig{}
	var err error
	initOnce.Do(func() {
		switch appEnv {
		case "development":
			err = Initialize("app.develop.yaml", cfg)
		case "production":
			err = Initialize("app.production.yaml", cfg)
		case "test":
			err = Initialize("app.test.yaml", cfg)
		default:
			panic("app evn error")
		}
		if err != nil {
			zaplog.Error("%+v", zap.Any("project init", err))
		}
		options = cfg
	})
}
